import threading
from support.ui.console import Log
from rich.progress import BarColumn, DownloadColumn, Progress, TextColumn, TimeRemainingColumn, ProgressColumn
from rich.console import Console
from typing import (
    IO,
    TYPE_CHECKING,
    Any,
    Callable,
    Dict,
    Iterable,
    List,
    Mapping,
    NamedTuple,
    Optional,
    TextIO,
    Tuple,
    Type,
    Union,
    cast,
)
class SmartProgress(Progress):
    TAG = "Progress"
    threadPool = None
    listener = None

    def __findNotRunId(self):
        taskId = None
        Log.d(SmartProgress.TAG, "find not run id from ")
        for task in self.tasks:
            if(not task.started or task.finished):
                taskId = task.id
                task._reset()
                break
        return taskId

    def __stop(self, taskid):
        for task in self.tasks:
            if(taskid == task.id):
                task.start_time = None
                break

    def getNotRunTasksCount(self):
        count = 0
        for task in self.tasks:
            if(not task.started or task.finished):
                count += 1
        return count

    def isFinished(self):
        ret = True
        for task in self.tasks:
            if(not task.finished):
                ret = False
                break
        return ret

    def __getCurrentValue(self, taskid, property):
        value = None
        property = property.lower()
        for task in self.tasks:
            if(task.id == taskid):
                if(property == "total"):
                    value = task.total
                elif(property == "completed"):
                    value = task.completed
                break
        return 0 if value is None else float(value)

    def __fixTotal(self, taskid: Optional[int], total: Optional[float]):
        return self.__getCurrentValue(taskid, "total") + total

    def updateTaskStatus(self, taskid, total: Optional[float] = None, advance: Optional[float] = None):
        if(total is not None):
            total = self.__fixTotal(taskid, total=total)
        self.update(task_id=taskid, total=total, advance=advance)

    def addOnFinishedListener(self, func):
        self.listener = func

    def restProgress(self, total: Optional[float] = 100, description: Optional[str] = None, visible: Optional[bool] = True, **fields: Any):
        taskid = self.__findNotRunId()
        if(taskid is None):
            taskid = self.add_task(**fields, description=description, total=total, visible=visible, start=False)
            self.__stop(taskid)
            Log.d(SmartProgress.TAG, "not found, so create a new one:", taskid)
        else:
            total = self.__fixTotal(taskid=taskid, total=total)
            self.update(**fields, task_id=taskid, total=total, description=description, visible=visible)
            Log.d(SmartProgress.TAG, "found! update progress:", taskid, description, fields)
        self.start_task(taskid)
        Log.d(SmartProgress.TAG, "get one task:", taskid)
        return taskid
    
